﻿using System;
using System.Collections.Generic;
using System.Text;
using Vortex.Drawing;
using Vortex.Debugging;

namespace Vortex.SceneFramework.Gui {
	/// <summary>
	/// Implements two-stated checkbox button. It has two states "Checked" or "Unchecked". Checkbox glyph is squared.
	/// </summary>
	public class Checkbox : Label {
		private bool _isChecked;

		#region Properties

		/// <summary>
		/// Gets or sets a value indicating whether this checkbox is checked.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this checkbox is checked; otherwise, <c>false</c>.
		/// </value>
		public virtual bool IsChecked {
			get { return _isChecked; }
			set { _isChecked = value; Style.Discard(); }
		}

		#endregion

		#region Drawing

		/// <summary>
		/// Checkbox drawing method
		/// </summary>
		/// <param name="canvas">The canvas to use for label drawing.</param>
		protected override void Draw(Vortex.Drawing.Canvas2D canvas) {
			Rect checkMarkRegion, textRegion;
			ComputeRegions(out checkMarkRegion, out textRegion);

			//draw background for glyph
			StyleDrawer.DrawBackground(canvas, Style, checkMarkRegion);

			if (IsChecked) {
				DrawCheckMark(canvas, checkMarkRegion);
			}

			//draw text is not empty
			if (!string.IsNullOrEmpty(Text)) {
				StyleDrawer.DrawText(canvas, Style, textRegion, Text);
			}
		}

		/// <summary>
		/// Draws the check mark.
		/// </summary>
		/// <param name="canvas">The canvas where draw check mark.</param>
		/// <param name="glyphRegion">The check mark region.</param>
		private void DrawCheckMark(Canvas2D canvas, Rect region) {
			Sprite checkboxSprite = Style.Get<Sprite>(Styles.Foreground);

			if (null != checkboxSprite) {
				//pay with checkbox-color-opacity
				ColorU checkboxColor = Style.Get<ColorU>(Styles.ForegroundColor);
				float checkboxOpacity = Style.Get<float>(Styles.ForegroundOpacity);
				if (checkboxOpacity < 1) {
					checkboxColor = checkboxColor.MultiplyAlpha(checkboxOpacity);
				}

				//very tricky way to change blending mode
				using (canvas <= Style.Get<Blending>(Styles.ForegroundBlending)) {
					region = region.Deflate(Style.Get<Rect>(Styles.ForegroundPadding));

					//if checkbox frame is empty then just stretch sprite to element bounds
					canvas.DrawSprite(region, checkboxSprite, checkboxColor);
				}
			}
		}

		/// <summary>
		/// Computes the checkbox regions.
		/// </summary>
		/// <param name="checkMarkRegion">The check mark region.</param>
		/// <param name="textRegion">The text region.</param>
		private void ComputeRegions(out Rect checkMarkRegion, out Rect textRegion) {
			Rect bounds = BoundingBox;

			if (bounds.Width > bounds.Height) {
				checkMarkRegion = Rect.FromBox(bounds.LeftTop, new Vector2(bounds.Height));
				textRegion = new Rect(checkMarkRegion.RightTop, bounds.RightBottom);
			} else {
				checkMarkRegion = Rect.FromBox(bounds.LeftTop, new Vector2(bounds.Width));
				textRegion = new Rect(checkMarkRegion.LeftBottom, bounds.RightBottom);
			}
		}

		#endregion

		#region Event Processing

		/// <summary>
		/// Processes the click of checkbox. It toggles the "IsChecked" property.
		/// </summary>
		/// <param name="eventInfo">The click event info.</param>
		protected internal override void ProcessClick(MouseEventInfo eventInfo) {
			if (eventInfo.Button == Vortex.Input.MouseButton.Left) {
				IsChecked = !IsChecked;
			}
			base.ProcessClick(eventInfo);
		}

		#endregion

	}
}
